/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package  cgl.narada.protocol;

import java.util.Vector;
 
/**
   In any complete recursive call, for calculation of the shortest path to 
   reach given node in the connectivity graph  we do not wish to get into 
   an infinite loop, the <i>path</i> keeps track of all the nodes that have 
   been visited during recursion to ensure that the same hop isn't taken 
   twice. This is especially important in the case of cyclic connectivities 
   like (a)->(b)->(c)->(a)
   @author Shrideep Pallickara
   $Revision$
   $Date$
*/

public class Path {
  /** In any complete recursive call we do not wish to get into an infinite 
      loop, the traversed hops keeps track of all the hops that have been 
      taken to ensure that the same hop isn't taken twice. This is especially 
      important in the case of cyclic connectivities like (a)->(b)->(c)->(a)
  */
  private Vector traversedHops;
  
  /** Keeps track of the cost incurred in traversing a hop. */
  private short cost;
  
  public Path() {
    cost = (short)0;
    traversedHops = new Vector();
  }
  
  /** Serves the same function that a copy constructor in C++ does. For the 
      Path object we need to at times pass the path by value instead of the
      Java default of pass by reference. This serves that purpose.
      @return A copy of the path on which this method was invoked. The hops
      and the costs associated with traversal are copied too 
  */
  public Path createCopy() {
    Path path  = new Path();
    Gateway[] hopsArray = getHopsTraversed();
    for (int i =0; i < hopsArray.length; i++) {
      path.addHop(hopsArray[i]);
    }
    path.addCost(getCost());
    return path;
  }


  /** This gets the cost associated with any path. The cost for traversal over
      an edge in the connectivity graph  is dictated by the link cost matrix.
      A path represents a series of edges  that were traversed in the 
      connectivity graph.
      @return The cost associated with a path.
  */
  public short getCost() {
    return cost;
  }
  
  /** This allows us to update the cost associated with a path.
      @param _cost - Increments the cost of the path by the specified value.
  */
  public void addCost(short _cost) {
    cost += _cost;
  }


  /** Updates the path, to reflect the node which was traversed during
      the recursion for calculation of shortest paths to a gateway
      @param gateway - The node in the connectivity graph that was traversed.
  */
  public void addHop(Gateway gateway) {
    traversedHops.addElement(gateway);
  }


  /** Check to see if a node was visited by one of the forks of a recursion
      process. 
      @return - <i>true</i> If the node was traversed, <i>false</i> otherwise.
  */
  public boolean nodeTraversed(Gateway gateway) {
    if (traversedHops.contains(gateway)) {
      return true;
    }
    return false;
  }
  

  /** Provides a list of the nodes in the connectivity graph that were visited
      @return - The nodes that were visted, as an array.
  */
  public Gateway[] getHopsTraversed() {
    Gateway[] hopsArray = new Gateway[traversedHops.size()];
    for (int i=0; i < traversedHops.size(); i++) {
      hopsArray[i] = (Gateway)traversedHops.elementAt(i);
    }
    return hopsArray;
  }

  /** Paths also maintain a cache of their shortest path to the vertex. 
      This allows a recursion to make use of an already computed path to
      arrive at its decision for the best path.
      @param path - The shortest path from a node to some other gateway. This
      path was computed during an earlier recursion process 
  */
  public void updatePath(Path path) {
    Gateway[] hopsArray = path.getHopsTraversed();
    cost += path.getCost();
    for (int i=0; i < hopsArray.length; i++) {
      traversedHops.addElement(hopsArray[i]);
    }
  }

  /** This method returns the best hop to take to reach the vertex node*/
  public Gateway getBestHopToTakeToReachNode() {
    if (traversedHops.size() != 0) {
      return (Gateway)traversedHops.lastElement();
    }
    /** A null indicates that node is a "hop" */
    return null;
  }
  
}
  



